refactor(tests): replace mailer mocks with email delivery assertions#2617
Conversation
|
@olleolleolle is this the most Rails idiomatic way of testing email sending? |
476cad2 to
58d14c1
Compare
…d of mocks Replaces mock expectations on mailer classes with assertions about ActionMailer::Base.deliveries. This improves test isolation for parallel execution. Changes: - 'creates an invitation for each student' now verifies emails sent via delivery count - 'creates an invitation for each coach' now verifies emails sent via delivery count - Tests verify recipient email addresses match expected members - Removes expect(mailer).to receive(:invite_student/coach) mocks
…ertions Replaces mock expectations with ActionMailer::Base.deliveries count assertions for #send_waiting_list_emails tests. Changes: - 'emails coaches when there are free coach spots' - verifies email delivery - 'does not email coaches when no coach spots' - verifies no emails sent - 'emails students when there are free student spots' - verifies email delivery - 'does not email students when no student spots' - verifies no emails sent Removes expect(WorkshopInvitationMailer).to receive(:notify_waiting_list) mocks
Replaces mock expectations with ActionMailer::Base.deliveries count assertions for reminder email tests. Changes: - 'emails all attending members' (monthly) - uses _without_delay method - 'emails all attending members' (workshop) - verifies email delivery count - 'emails waiting list' - uses _without_delay method Notes: - Monthly and waiting list tests remain marked :wip as they were before - These methods are async and require _without_delay for sync testing Removes expect(Mailer).to receive(:attendance_reminder) mocks
Replaces mock expectations with ActionMailer::Base.deliveries count assertions for #send_meeting_emails tests. Changes: - 'emails all invitees that are not banned' - verifies email count excludes banned - 'emails valid invitees only once' - verifies email count excludes already invited Uses _without_delay method for synchronous testing. Removes expect(MeetingInvitationMailer).to receive(:invite) mocks
Replaces mock expectations with ActionMailer::Base.deliveries count assertions for async behavior tests. Changes: - 'sends invitation emails' (async context) - verifies email delivery - 'sends attendance reminder emails' (async context) - verifies email delivery Uses _without_delay methods for synchronous testing. Removes remaining expect(WorkshopInvitationMailer).to receive mocks
…ertions Simplifies after create hook tests by removing mock-based tests and replacing with direct email delivery verification. Changes: - Consolidates two mock-based tests into one email delivery test - Verifies email is sent and has expected subject Removes allow().to receive() and have_received() mocks
…ssertions Replaces spy-based mock test with email delivery verification. Changes: - 'sends an eligibility check email' - verifies email delivery count and recipient Removes allow().to receive() and have_received() mocks
…sertions Replaces spy-based mock test with email delivery verification. Changes: - 'sends an attendance warning email' - finds email by recipient and subject - Uses flexible matching to account for other emails in deliveries Removes allow().to receive() and have_received() mocks
… assertions Replaces expect_any_instance_of mocks with ActionMailer::Base.deliveries verification for all welcome email scenarios. Changes: - First-time coach subscription - verifies email sent and contains 'coach' - First-time student subscription - verifies email sent and contains 'student' - Second subscription tests - clears deliveries and verifies no new emails - Unsubscribe/resubscribe tests - verifies no duplicate emails sent Adds before hook to clear deliveries for consistent test isolation. Removes all expect_any_instance_of(MemberMailer) mocks which were problematic for parallel test execution.
…rtions Replaces expect_any_instance_of mocks with direct mail content verification for welcome email tests. Changes: - 'sends the coach welcome email to coaches' - verifies email body contains coach text - 'sends the student welcome email to students' - verifies email body contains student text - 'sends a ban email to a member' - verifies recipient and email body Removes all expect_any_instance_of(MemberMailer) mocks which were problematic for parallel test execution.
The delivery-assertion refactor incorrectly asserted that already-reminded invitations should have reminded_at as nil. The fabricator sets reminded_at to 2.days.ago, so the correct assertion is that it remains unchanged (still ~2 days ago).
58d14c1 to
662ab6a
Compare
Note on the fix for
|
|
@olleolleolle, this is now finally ready for your review |
olleolleolle
left a comment
There was a problem hiding this comment.
(Perhaps: mail.body.encoded - can perhaps try expect(mail.body).to include("…”) for those checks. No big deal.)
Huzzah!
Summary
Replaces mock-based mailer tests with assertions on ActionMailer::Base.deliveries. This improves test isolation and eliminates flaky tests in parallel test execution.
Problem
The existing tests used
expect(Mailer).to receive(:method)andexpect_any_instance_of(Mailer)which:Solution
Replace mock expectations with assertions on actual email delivery:
expect { action }.to change { ActionMailer::Base.deliveries.count }expect(email.to).to include(member.email)expect(email.body.encoded).to match(/pattern/)Files Changed
spec/support/shared_examples/behaves_like_sending_workshop_emails.rbspec/models/invitation_manager_spec.rbspec/models/feedback_request_spec.rbspec/models/eligibility_inquiry_spec.rbspec/models/attendance_warning_spec.rbspec/features/subscribing_to_emails_spec.rbspec/mailers/member_mailer_spec.rbTest Results
All 59 affected tests pass:
Benefits